package com.itheima.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.dao.MenuDao;
import com.itheima.dao.RoleDao;
import com.itheima.dao.UserDao;
import com.itheima.entity.PageResult;
import com.itheima.entity.Result;
import com.itheima.pojo.Menu;
import com.itheima.pojo.Role;
import com.itheima.pojo.User;
import com.itheima.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 菜单接口实现类
 */
@Service(interfaceClass = MenuService.class)
@Transactional
public class MenuServiceImpl implements MenuService {

    @Autowired
    private UserDao userDao;
    @Autowired
    private RoleDao roleDao;
    @Autowired
    private MenuDao menuDao;
    @Override
    public List<Menu> findMenuByUserName(String username) {
        //先根据username查出userId,然后查出对应的角色,再查出对应一级菜单
        User user = userDao.findByUsername(username);
        List<Menu> mainMenus = menuDao.findMainMenusByUserId(user.getId());
        if (mainMenus != null && mainMenus.size()>0){
            Map<String,Integer> map = new HashMap<>();
            map.put("userId",user.getId());
            for (Menu mainMenu : mainMenus) {
                map.put("parentMenuId",mainMenu.getId());
                List<Menu> childMenus = menuDao.findChildMenusByUserIdAndParentMenuId(map);
                if (childMenus!=null && childMenus.size()>0){
                    mainMenu.setChildren(childMenus);
                }
            }
            return mainMenus;
        }
        return null;
    }

    /**
     * 分页查询
     *
     * @param currentPage
     * @param pageSize
     * @param queryString
     * @return
     */
    public PageResult findPage(Integer currentPage, Integer pageSize, String queryString) {

        PageHelper.startPage(currentPage,pageSize);
        /*插件工具用法需要另外查询理解*/
        Page<Menu> page = menuDao.selectByCondition(queryString);
        /*查询子菜单信息，设置到对应主菜单中*/
        for (Menu menu : page) {

            Integer parentMenuId = menu.getId();
            List<Menu> children = menuDao.findchildren(parentMenuId);
            menu.setChildren(children);

        }

        return new PageResult(page.getTotal(),page.getResult());

    }

    /**
     * 查询父类菜单信息
     *
     * @return
     */
    @Override
    public List<Menu> findAllParentMenu() {
        return menuDao.findAllParentMenu();
    }

    /**
     * 通过id查询父类菜单路径信息
     *
     * @param id
     * @return
     */
    public String findPathById(Integer id) {
        return menuDao.findPathById(id);
    }

    /**
     * 通过名称查询菜单是否存在
     *
     * @param name
     * @return
     */
    public Long findByName(String name) {
        return menuDao.findByName(name);
    }

    /**
     * 通过优先级查询菜单是否存在
     *
     * @param map
     * @return
     */
    @Override
    public Integer findByPriority(Map map) {
        return menuDao.findByPriority(map);
    }

    /**
     * 新增菜单
     *
     * @param menu
     */
    public void add(Menu menu) {
        menuDao.add(menu);
    }

    /**
     * 查询主菜单最大项
     *
     * @return
     */
    public String findMaxPath() {
        return menuDao.findMaxPath();
    }

    /**
     * 通过id查询菜单信息
     *
     * @param id
     * @return
     */
    public Menu findById(Integer id) {
        return menuDao.findById(id);
    }

    /**
     * 更新菜单
     *
     * @param menu
     * @return
     */
    public Result edit(Menu menu) {

        /*判断是否重名*/
        Long nameCount = menuDao.findByName(menu.getName());
        if (nameCount > 1) {
            /*不同菜单中菜单名已存在 返回提示*/
            return new Result(false, "菜单名称已存在，请修改后再尝试");

        } else if (nameCount == 1) {
            /*判断是否为同一菜单提交修改*/
            Menu dbMenu = menuDao.findById(menu.getId());
            if (dbMenu.getId() != menu.getId()) {
                return new Result(false, "菜单名称已存在，请修改后再尝试");
            }
        }

        /*传入数据*/
        Integer priority = menu.getPriority();
        Integer parentMenuId = menu.getParentMenuId();
        /*数据库数据*/
        Menu dbMenu = menuDao.findById(menu.getId());


        /*判断是否是子菜单(这里parentMenuId是前台传入的数据)*/
        if (parentMenuId != null) {

            /*判断子菜单是否有修改父菜单选项*/
            Integer dbParentMenuId = dbMenu.getParentMenuId();

            /*判断是否为父菜单改为子菜单提交*/
            if (dbParentMenuId == null) {

                /*为父菜单 不允许修改为子菜单*/
                return new Result(false, "父菜单不能修改为子菜单，求修改后提交");

            }

            /*判断子菜单是否有修改父菜单选项*/
            if (dbParentMenuId != parentMenuId) {

                /*设置新父类id*/
                menu.setParentMenuId(parentMenuId);
                /*判断子菜单优先级是否可行*/
                /*封装 优先级和菜单等级数据*/
                Integer priorityCount = this.getPriority(priority, parentMenuId);
                if (priorityCount > 0) {
                    /*菜单已存在 返回提示*/
                    return new Result(false, "菜单优先级已存在，请修改后再尝试");
                }

                /*获取新父菜单路径*/
                Menu newMenu = menuDao.findById(parentMenuId);
                String newPath = newMenu.getPath();
                /*修改新path路径*/
                menu.setPath("/" + newPath + "-" + priority);

            } else {

                /*没有修改父类菜单*/
                /*判断子菜单优先级是否可行*/
                if(dbMenu.getPriority() != priority){
                    /*如果传入优先级与不同，则验证新优先级情况*/
                    Integer priorityCount = this.getPriority(priority, parentMenuId);
                    if (priorityCount > 0) {
                        /*菜单已存在 返回提示*/
                        return new Result(false, "菜单优先级已存在，请修改后再尝试");
                    }
                    /*修改新path路径*/
                    String path = menuDao.findPathById(parentMenuId);
                    menu.setPath("/" + path + "-" + priority);
                }/*否则不验证优先级*/

            }

        } else {

            /*判断是否为子类菜单修改为父类菜单*/
            if (dbMenu.getParentMenuId() != null) {

                /*是子菜单不允许修改为父菜单*/
                return new Result(false, "子菜单不能修改为父菜单，请修改后再尝试");

            }
            if(dbMenu.getPriority() != priority) {
                /*如果传入优先级与不同，则验证新优先级情况*/
                Integer count = this.getPriority(priority, parentMenuId);
                if (count > 0) {
                    return new Result(false, "菜单优先级已存在，请修改后再尝试");
                }
                /*修改新path路径*/
                String path = menuDao.findPathById(parentMenuId);
                menu.setPath("/" + path + "-" + priority);
            }/*否则不验证优先级*/

        }
        menuDao.edit(menu);

        return new Result(true, "更新菜单成功");
    }

    /**
     * 删除菜单
     *
     * @param id
     */
    public Result delete(Integer id) {

        /*是否有角色使用该菜单*/
        Integer count = menuDao.findRoleAndMenuById(id);
        if (count > 0) {
            return new Result(false,"有角色使用了该菜单，不能直接删除，请删除后重试");
        }
        /*判断是否是父菜单且有子菜单*/
        List<Menu> childrenMenu = menuDao.findchildren(id);
        if (childrenMenu == null && childrenMenu.size() == 0){
            return new Result(false,"该菜单有子菜单，删除失败");
        }
        menuDao.delete(id);
        return new Result(true,"删除菜单成功");

    }

    /**
     * 判断菜单优先级是否可以用
     * @param priority
     * @param parentMenuId
     * @return
     */
    public Integer getPriority(Integer priority,Integer parentMenuId) {

        Map<String,Object> pathAndPriorityMap = new HashMap<>();
        pathAndPriorityMap.put("priority",priority);
        pathAndPriorityMap.put("parentMenuId",parentMenuId);

        Integer priorityCount = menuDao.findByPriority(pathAndPriorityMap);
        return priorityCount;

    }


    @Override
    public Set<Menu> findAll() {
        return menuDao.findAll();
    }
}
